﻿Imports System.Reflection
Imports System.Collections.Generic


Public Class DOPropertyHelper
    Private m_infosLookup As Dictionary(Of String, Integer)
    Private m_infos() As DOInfo
    Private m_key As String
    Private m_type As Type
    Private m_primaryKeyPropertyName As String


    Public Sub New(ByVal t As Type)
        m_infosLookup = New Dictionary(Of String, Integer)
        Me.m_type = t
        Me.m_key = t.ToString()
        Me.CacheStructure()
    End Sub

    ''' <summary>
    ''' Cache the structure of this object reflection in a high level of detail
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub CacheStructure()
        Dim myPropertyInfo() As PropertyInfo
        Dim myPropertyNames As New List(Of String)
        Dim myInfoList As New List(Of DOInfo)
        Dim tmpAttr() As Object
        myPropertyInfo = m_type.GetProperties()

        For i As Integer = 0 To myPropertyInfo.Length - 1
            If myPropertyInfo(i).DeclaringType.Equals(m_type) Then
                tmpAttr = myPropertyInfo(i).GetCustomAttributes(GetType(PersistAttribute), False)
                If tmpAttr.Length > 0 Then
                    myPropertyNames.Add(myPropertyInfo(i).Name)

                    Dim element As New DOInfo
                    element.CastType = myPropertyInfo(i).DeclaringType
                    element.PropertyName = myPropertyInfo(i).Name
                    element.TypeName = myPropertyInfo(i).PropertyType.ToString()
                    tmpAttr = myPropertyInfo(i).GetCustomAttributes(GetType(PrimaryKeyAttribute), False)
                    element.PrimaryKey = IIf(tmpAttr.Length > 0, True, False)
                    tmpAttr = myPropertyInfo(i).GetCustomAttributes(GetType(IdentityAttribute), False)
                    element.Identity = IIf(tmpAttr.Length > 0, True, False)
                    myInfoList.Add(element)
                    m_infosLookup.Add(element.PropertyName, myInfoList.Count - 1)
                    If element.PrimaryKey Then m_primaryKeyPropertyName = element.PropertyName
                End If
            End If
        Next
        m_infos = myInfoList.ToArray()
    End Sub

    Public Function IsIdentity(ByVal propertyIndex As Integer) As Boolean
        Return m_infos(propertyIndex).Identity
    End Function

    Public Function IsIdentity(ByVal propertyName As String) As Boolean
        Dim index As Integer = 0
        If Not Me.m_infosLookup.TryGetValue(propertyName, index) Then Return False
        Return Me.IsIdentity(index)
    End Function

    Public Function IsPrimaryKey(ByVal propertyIndex As Integer) As Boolean
        Return m_infos(propertyIndex).PrimaryKey
    End Function

    Public Function IsPrimaryKey(ByVal propertyName As String) As Boolean
        Dim index As Integer = 0
        If Not Me.m_infosLookup.TryGetValue(propertyName, index) Then Return False
        Return Me.IsPrimaryKey(index)
    End Function

    Public Function IsPersistant(ByVal propertyName As String) As Boolean
        Return m_infosLookup.ContainsKey(propertyName)
    End Function

    Public ReadOnly Property DOTypeName() As String
        Get
            Return Me.m_key
        End Get
    End Property

    Public ReadOnly Property PropertyInfo() As DOInfo()
        Get
            Return Me.m_infos
        End Get
    End Property

    Public Function GetInfo(ByVal index As Integer) As DOInfo
        Return Me.m_infos(index)
    End Function

    Public Function GetInfo(ByVal propertyName As String) As DOInfo
        Dim index As Integer
        If Not m_infosLookup.TryGetValue(propertyName, index) Then Return Nothing
        Return Me.m_infos(index)
    End Function

    Public ReadOnly Property PrimaryKeyName() As String
        Get
            Return Me.m_primaryKeyPropertyName
        End Get
    End Property


End Class
